package com.example.zuul;

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {

	public static void main(String[] args) {
		SpringApplication.run(ZuulApplication.class, args);
	}

    @Bean
    ServletRegistrationBean servletRegistrationBean() {
        HystrixMetricsStreamServlet hystrixMetricsStreamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean<HystrixMetricsStreamServlet> hystrixMetricsStreamServletServletRegistrationBean = new ServletRegistrationBean<>(hystrixMetricsStreamServlet);
        hystrixMetricsStreamServletServletRegistrationBean.addUrlMappings("/actuator/hystrix.stream");
        return hystrixMetricsStreamServletServletRegistrationBean;
    }

    @Component
    class ZuulFallbackProvider implements FallbackProvider {
        @Override
        public String getRoute() {
            return "hystrix";
        }

        @Override
        public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
            return new ClientHttpResponse() {
                @Override
                public HttpStatus getStatusCode() throws IOException {
                    return HttpStatus.OK;
                }

                @Override
                public int getRawStatusCode() throws IOException {
                    return this.getStatusCode().value();
                }

                @Override
                public String getStatusText() throws IOException {
                    return this.getStatusCode().getReasonPhrase();
                }

                @Override
                public void close() {
                }

                @Override
                public InputStream getBody() throws IOException {
                    return new ByteArrayInputStream("服务器异常稍后再试！".getBytes());
                }

                @Override
                public HttpHeaders getHeaders() {
                    return HttpHeaders.EMPTY;
                }
            };
        }
    }

    @Component
    class ZuulZuulFilter extends ZuulFilter {

        @Override
        public String filterType() {
            return FilterConstants.PRE_TYPE;
        }

        @Override
        public int filterOrder() {
            return FilterConstants.SEND_ERROR_FILTER_ORDER;
        }

        @Override
        public boolean shouldFilter() {
            String path = RequestContext.getCurrentContext().getRequest().getRequestURI();
            return false;
        }

        @Override
        public Object run() throws ZuulException {
            RequestContext ctx = RequestContext.getCurrentContext();
            ctx.setResponseStatusCode(HttpServletResponse.SC_OK);
            if (ctx.getResponseBody() == null) {
                ctx.setResponseBody("Hello World");
                ctx.setSendZuulResponse(false);
            }
            return null;
        }
    }

	}
